#include <WiFi.h>                  // 包含WiFi库，用于ESP32的WiFi功能
#include <WiFiClient.h>            // 包含WiFiClient库，用于创建客户端连接

// Wi-Fi SSID和密码
const char* ssid = "666_plus";         // WiFi网络的SSID名称
const char* password = "qaz666plm"; // WiFi网络的密码

// Netty服务器的IP地址和端口号
const char* serverIP = "192.168.1.101"; // Netty服务器的IP地址
const int serverPort = 6666;            // Netty服务器监听的端口号

// LED连接的引脚
const int LED = 2;                      // LED连接在数字引脚2

// WiFi连接状态变量
WiFiClient client;                      // 创建一个WiFiClient对象，用于建立TCP连接

// setup()函数，在程序开始时执行一次
void setup() {
  Serial.begin(115200);                 // 初始化串口通信，设置波特率为115200
  pinMode(LED, OUTPUT);                 // 设置LED引脚为输出模式

  WiFi.begin(ssid, password);           // 开始尝试连接到指定的WiFi网络
  while (WiFi.status() != WL_CONNECTED) { // 循环等待WiFi连接成功
    delay(500);
    Serial.print(".");                  // 输出点号，表示正在尝试连接
  }

  // 当Wi-Fi连接成功后，点亮LED
  digitalWrite(LED, HIGH);              // 设置LED引脚为高电平，点亮LED

  Serial.println("");                   // 换行，清理串口监视器的最后一点
  Serial.println("WiFi connected");     // 输出WiFi连接成功的信息
  Serial.println("IP address: ");       // 输出ESP32的本地IP地址前缀
  Serial.println(WiFi.localIP());       // 输出ESP32的本地IP地址
  connectToServer();                    // 尝试连接到Netty服务器
}

// loop()函数，在setup()执行后，持续循环执行
void loop() {
  if (!client.connected()) {            // 检查与服务器的连接状态
    connectToServer();                  // 如果连接已断开，尝试重新连接
  }

  handleIncomingData();                 // 调用函数处理从服务器接收的数据
}

// connectToServer()函数，尝试连接到Netty服务器
void connectToServer() {
  Serial.print("Attempting to connect to Netty server..."); // 输出正在尝试连接服务器的信息
  if (client.connect(serverIP, serverPort)) {               // 尝试连接到服务器
    Serial.println("Connected.");                           // 输出连接成功的信息

    // 新增代码：发送注册命令
    sendRegisterCommand();                                  // 发送注册命令
  } else {
    Serial.println("Connection failed.");                   // 输出连接失败的信息
  }
}

// sendRegisterCommand()函数，发送注册命令
void sendRegisterCommand() {
  Serial.println("Sending register command...");            // 输出发送注册命令的信息
  client.print("register\n");                               // 向服务器发送"register"命令
}

// handleIncomingData()函数，处理从服务器接收的数据
void handleIncomingData() {
  while (client.available()) {                              // 检查是否有数据可读
    String serverMessage = client.readStringUntil('\n');    // 读取直到遇到换行符'\n'的数据
    if (serverMessage.length() > 0) {                       // 如果接收到的数据非空
      Serial.print("Received message: ");                   // 输出接收到的消息前缀
      Serial.println(serverMessage);                        // 输出接收到的完整消息

      if (serverMessage.equals("on")) {                     // 如果消息内容为"on"
        digitalWrite(LED, HIGH);                            // 设置LED引脚为高电平，点亮LED
        Serial.println("LED turned on.");                   // 输出LED开启的信息
      } else if (serverMessage.equals("off")) {             // 如果消息内容为"off"
        digitalWrite(LED, LOW);                             // 设置LED引脚为低电平，关闭LED
        Serial.println("LED turned off.");                  // 输出LED关闭的信息
      }
    }
  }
}